﻿namespace TanzimSaqib.NoBrainer
{
    using System;

    /// <summary>
    /// Registers the caching implementation with the container. Register either
    /// EntlibCacheResolver or NoCacheResolver, based upon settings
    /// </summary>
    internal class MvcCache
    {
        private static ICache _Cache;
        public static ICache Instance
        {
            get { return _Cache ?? (_Cache = MvcDependencies.Container.Resolve<ICache>()); }
        }

        public static string ControlGraph(string pageName)
        {
            return "ControlGraph=" + pageName;
        }

        public static string ControlList(string pageName)
        {
            return "ControlList=" + pageName;
        }

        public static string CmsMvcXml(string fullPath)
        {
            return "CmsMvcXml=" + fullPath;
        }

        //public static string CmsControlGraph(string pageName)
        //{
        //    return "CmsControlGraph=" + pageName;
        //}

        public static void Setup()
        {
            var x = new EntlibCacheResolver();

            bool enabled;
            if (bool.TryParse(ConfigurationManager.AppSettings[FxResources.CacheManagerName], out enabled)
                && enabled)
            {
                MvcDependencies.Container.Register<ICache>(c => new EntlibCacheResolver());

            }
            else
            {
                MvcDependencies.Container.Register<ICache>(c => new NoCacheResolver());
            }
        }
    }

    /// <summary>
    /// A caching implementation, uses Caching Application Block as the internal
    /// caching engine
    /// </summary>
    public class EntlibCacheResolver : ICache
    {
        private readonly static ICacheManager _CacheManager = CacheFactory.GetCacheManager(FxResources.CacheManagerName);

        #region ICache Members

        public void Add(string key, object value, string dependencyFullFileName)
        {
            throw new NotImplementedException();
        }

        public void Add(string key, object value, TimeSpan timeout)
        {
            _CacheManager.Add(key, value, CacheItemPriority.Normal, null,
                new AbsoluteTime(DateTime.Now.Add(timeout)));
        }

        public void Add(string key, object value)
        {
            _CacheManager.Add(key, value);
        }

        public bool Contains(string key)
        {
            return _CacheManager.Contains(key);
        }

        public void Flush()
        {
            _CacheManager.Flush();
        }

        public void Remove(string key)
        {
            _CacheManager.Remove(key);
        }

        public void Set(string key, object value, TimeSpan timeout)
        {
            if (_CacheManager.Contains(key))
                _CacheManager.Remove(key);
            this.Add(key, value, timeout);
        }

        public void Set(string key, object value)
        {
            if (_CacheManager.Contains(key))
                _CacheManager.Remove(key);
            this.Add(key, value);
        }

        public object Get(string key)
        {
            return _CacheManager.GetData(key);
        }

        public void Put(string key, object item)
        {
            _CacheManager.Add(key, item);
        }

        #endregion
    }

    public class NoCacheResolver : ICache
    {
        #region ICache Members

        public void Add(string key, object value, string dependencyFullFileName)
        {

        }

        public void Add(string key, object value, TimeSpan timeout)
        {

        }

        public void Add(string key, object value)
        {

        }

        public bool Contains(string key)
        {
            return false;
        }

        public void Flush()
        {

        }

        public object Get(string key)
        {
            return null;
        }

        public void Remove(string key)
        {

        }

        public void Set(string key, object value, TimeSpan timeout)
        {

        }

        public void Set(string key, object value)
        {

        }

        #endregion
    }
}
